﻿using System;
using System.Runtime.Remoting.Messaging;
using System.Threading;

namespace ConsoleDemo
{
    delegate int Mydel(int x, int y);

    public class BeginInvokeDemo
    {
        // 例子1
        public static int Sum(int x, int y)                 //异步方法
        {
            Console.WriteLine("                   InSide Sum1");
            Thread.Sleep(1000);
            Console.WriteLine("                   InSide Sum2");
            return x + y;
        }

        public static void Callback_(IAsyncResult iar)    //回调方法        无论如何回调方法中的内容必须在异步方法执行完后才执行    
        {
            Console.WriteLine("                     Inside CallWhenDone");
            AsyncResult ar = (AsyncResult)iar;      //里氏转换，如果父类中装的是子类的对象，那么可以将这个父类转换为子类对象   
            Mydel del = (Mydel)ar.AsyncDelegate;    //通过AsyncResult类对象的AsyncDelegate属性转化为合适的Mydel委托类型
            long result = del.EndInvoke(iar);
            Console.WriteLine("                     The result is: {0}", result);
        }

        public static void BeginInvokeDemoCall1()
        {
            Mydel Del = new Mydel(Sum);
            Console.WriteLine("Before BeginInvoke");
            IAsyncResult iar = Del.BeginInvoke(7, 8, new AsyncCallback(Callback_), Del);                   //Del焕成null结果也一样
            Console.WriteLine("Doing more work in main");
            Thread.Sleep(500);
            Console.WriteLine("Done with Main.Exiting");
        }

        // 例子2
        static int Work(string s) { return s.Length; }

        static void Done(IAsyncResult iar)
        {
            Console.WriteLine("                     Inside Done Method");
            var target = (Func<string, int>)iar.AsyncState;
            Console.WriteLine(target);
            int result = target.EndInvoke(iar);
            Console.WriteLine("String length is: " + result);
        }

        public static void BeginInvokeDemoCall2()
        {
            Func<string, int> method = Work;
            Console.WriteLine("Before BeginInvoke");
            IAsyncResult iar = method.BeginInvoke("test", Done, method);
            Console.WriteLine("Doing more work in main");
            Thread.Sleep(500);
            Console.WriteLine("Done with Main.Exiting");
        }
    }
}
